#include "threadpool.h"
#include <iostream>

ThreadPool::ThreadPool(size_t threads) : running(false) {
    if (threads == 0) {
        throw std::invalid_argument("线程池线程数量不能为0");
    }

    running = true;

    // 创建指定数量的工作线程
    workers.reserve(threads);
    for (size_t i = 0; i < threads; ++i) {
        workers.emplace_back(&ThreadPool::worker_loop, this);
    }
}

ThreadPool::ThreadPool(ThreadPool&& other) noexcept
    : workers(std::move(other.workers)),
    tasks(std::move(other.tasks)),
    running(other.running) {
    other.running = false;
}

ThreadPool& ThreadPool::operator=(ThreadPool&& other) noexcept {
    if (this != &other) {
        // 停止当前线程池
        running = false;
        condition.notify_all();
        for (auto& worker : workers) {
            if (worker.joinable()) {
                worker.join();
            }
        }

        // 移动资源
        workers = std::move(other.workers);
        tasks = std::move(other.tasks);
        running = other.running;
        other.running = false;
    }
    return *this;
}

ThreadPool::~ThreadPool() {
    // 停止所有工作线程
    {
        std::unique_lock<std::mutex> lock(queue_mutex);
        running = false;
    }

    // 唤醒所有等待的线程
    condition.notify_all();

    // 等待所有线程完成
    for (auto& worker : workers) {
        if (worker.joinable()) {
            worker.join();
        }
    }
}

void ThreadPool::worker_loop() {
    while (true) {
        std::function<void()> task;

        // 等待并获取一个任务
        {
            std::unique_lock<std::mutex> lock(queue_mutex);

            // 等待直到有任务或线程池停止
            condition.wait(lock, [this] {
                return !running || !tasks.empty();
            });

            // 如果线程池已停止且任务队列为空，则退出
            if (!running && tasks.empty()) {
                return;
            }

            // 从队列中获取任务
            task = std::move(tasks.front());
            tasks.pop();
        }

        // 执行任务
        try {
            task();
        } catch (const std::exception& e) {
            // 可以在这里添加错误处理逻辑
            std::cerr << "线程池任务执行出错: " << e.what() << std::endl;
        } catch (...) {
            std::cerr << "线程池任务执行时发生未知错误" << std::endl;
        }
    }
}

// 示例任务1：计算两个数的和
int sum(int a, int b) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    return a + b;
}

// 示例任务2：计算斐波那契数列（递归实现，耗时较长）
int fibonacci(int n) {
    if (n <= 1) return n;
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
    return fibonacci(n-1) + fibonacci(n-2);
}

// 示例任务3：无返回值的任务
void print_message(const std::string& msg, int id) {
    std::this_thread::sleep_for(std::chrono::milliseconds(150));
    std::cout << "任务 " << id << ": " << msg << " (线程ID: "
              << std::this_thread::get_id() << ")" << std::endl;
}
void ThreadPool::test() {
    try {
        // 创建线程池，使用4个线程
        ThreadPool pool(4);
        std::cout << "创建了包含 " << pool.size() << " 个线程的线程池" << std::endl;

        // 存储所有任务的future
        std::vector<std::future<int>> futures;

        // 提交一批计算任务
        std::cout << "\n提交一批加法任务..." << std::endl;
        for (int i = 0; i < 8; ++i) {
            futures.emplace_back(
                pool.enqueue(sum, i, i * 2)
                );
        }

        // 提交一些斐波那契计算任务
        std::cout << "\n提交斐波那契计算任务..." << std::endl;
        for (int i = 10; i < 15; ++i) {
            futures.emplace_back(
                pool.enqueue(fibonacci, i)
                );
        }

        // 提交一些打印任务
        std::cout << "\n提交打印任务..." << std::endl;
        for (int i = 0; i < 5; ++i) {
            pool.enqueue(print_message, "这是一个测试消息", i);
        }

        // 等待所有计算任务完成并输出结果
        std::cout << "\n等待所有计算任务完成..." << std::endl;
        for (size_t i = 0; i < futures.size(); ++i) {
            std::cout << "任务 " << i << " 结果: " << futures[i].get() << std::endl;
        }

        std::cout << "\n所有任务已完成" << std::endl;

    } catch (const std::exception& e) {
        std::cerr << "发生错误: " << e.what() << std::endl;
    }
}
